package Element;

import java.awt.*;
import java.awt.geom.*;

import Element.Geom.*;
import DistSys.*;

public class Sect extends AbsElem implements Cloneable {
    public static AbsElem objActiveTemp;  //a developer's version of ActiveTemplate

    public Sect(){ }

    public Object clone(){
        Sect created = new Sect();
        this.copyTo(created); // copy AbsElem attributes to created
        //created.setDftTemp(this.getDftTempName());
        //created.rel  = (ReliaInd) (this.rel.clone());
        //created.ckt  = (CktLaw) (this.ckt.clone());
        created.geom = (SwtGeom) (((SwtGeom)this.geom).clone());
        return created;
    }

    public int getType() { return SysConst.TYPE_SECTIONIZER; }

    public void draw(Graphics2D g2, double dist, double theta) {
        int x1 = geom.x1, y1 = geom.y1, x2 = geom.x2, y2 = geom.y2;

        int Ax = x1 + (int)(dist * Math.cos(theta)/4);
        int Ay = y1 + (int)(dist * Math.sin(theta)/4);
        int Bx = x1 + (int)(dist * Math.cos(theta)*3/4);
        int By = y1 + (int)(dist * Math.sin(theta)*3/4);
        int Cx = (Ax + Bx)/2;
        int Cy = (Ay + By)/2;

        g2.drawLine(x1,y1, Ax,Ay);     //don't rotate the handle line
        g2.drawLine(Bx,By, x2,y2);

        double length = Math.sqrt((double) ((Ax-Bx)*(Ax-Bx) + (Ay-By)*(Ay-By)));
        int tmp1 = (int) ((double)(Ax+Bx)/2.0 - length/2.0);
        int tmp2 = (int) ((double)(Ay+By)/2.0 - length/2.0);
        // don't use Cx - length/2 to avoid loss of precision

        AffineTransform t = geom.t;
        t.setToRotation(theta, Cx, Cy);
        g2.transform(t);

        if (((SwtGeom)geom).getIsOpen()) {
            g2.fillOval(tmp1,tmp2, (int)(length),(int)(length));
        } else {
            g2.drawOval(tmp1,tmp2, (int)(length),(int)(length));
        }
    }

    /**
     * Returns whether the data field with the given index "makes sense" for
     * this element type or not.
     *
     * @param index  a <code>int</code> specifying the index.
     *
     * @return  <code>true</code> if the data field "makes sense",
     *          <code>false</code> otherwise
     */
    public boolean getDataExists(int index) {
        // A switch is used here to be independent of the
        // AbsElem.DATA_* constant's real values.
        switch(index) {
            case AbsElem.DATA_ZONE:
            case AbsElem.DATA_LAYER:
            case AbsElem.DATA_RATED_POWER:
            case AbsElem.DATA_RATED_CURR:
            case AbsElem.DATA_ZONE_BUFFER0:
            case AbsElem.DATA_ZONE_BUFFER2:
            case AbsElem.DATA_ZONE_BUFFER4:
            case AbsElem.DATA_ZONE_BUFFER1:
            case AbsElem.DATA_ZONE_BUFFER3:
            case AbsElem.DATA_TEMP_FAULT:
            case AbsElem.DATA_SUST_FAULT:
            case AbsElem.DATA_OPEN_CKT:
            case AbsElem.DATA_MTTR:
            case AbsElem.DATA_MTTS:
            case AbsElem.DATA_OPER_FAIL:
            case AbsElem.DATA_VOLT_SAG_LEVEL:
            case AbsElem.DATA_RESISTANCE:
            case AbsElem.DATA_REACTANCE:
            case AbsElem.DATA_SHUNT_COND:
            case AbsElem.DATA_SHUNT_SUCEP:
            case AbsElem.DATA_CAPITAL_COST:
            case AbsElem.DATA_OM_COST:
            case AbsElem.DATA_FONT_SIZE:
            case AbsElem.DATA_IN_OPT_LIB:
            case AbsElem.DATA_MAINT_DUR:
            case AbsElem.DATA_MAINT_RATE:
            case AbsElem.DATA_NORM_OPEN:
            case AbsElem.DATA_OPTIMIZABLE:
            case AbsElem.DATA_PHASE:
            case AbsElem.DATA_STUDY_AREA:
            case AbsElem.DATA_UPGRADE_COST:
            case AbsElem.DATA_YEAR:
                return true;
            default:
                return false;
        }
    }

    /**
     * Returns whether the result field with the given index "makes sense" for
     * this element type or not.
     *
     * @param index  a <code>int</code> specifying the index.
     *
     * @return  <code>true</code> if the result field "makes sense",
     *          <code>false</code> otherwise
     */
    public boolean getResultExists(int index) {
        // A switch is used here to be independent of the
        // AbsElem.RES_* constant's real values.
        switch(index) {
            case AbsElem.RES_QUERY_SCORE:
            case AbsElem.RES_QUERY_SCORE_PERC:
            case AbsElem.RES_MOMENT_INT:
            case AbsElem.RES_SUST_INT:
            case AbsElem.RES_OUT_DUR:
            case AbsElem.RES_VOLT_SAGS:
            case AbsElem.RES_SWT_OPER:
            case AbsElem.RES_TRIP_OPER:
            case AbsElem.RES_RECLOSE_OPER:
            case AbsElem.RES_BLOCK_OPER:
            case AbsElem.RES_CAPA_CONS:
            case AbsElem.RES_CAPA_CONS_KVA:
            case AbsElem.RES_KVA_FLOW:
            case AbsElem.RES_PF:
            case AbsElem.RES_VOLT_MAG:
            case AbsElem.RES_VOLT_ANG:
            case AbsElem.RES_CURR_MAG:
            case AbsElem.RES_CURR_ANG:
            case AbsElem.RES_SHORTCIRC_CURR:
            case AbsElem.RES_VOLT_DROP:
            case AbsElem.RES_CURR_LOADING:
            case AbsElem.RES_KVA_RATING:
            case AbsElem.RES_MAIFI:
            case AbsElem.RES_SAG:
            case AbsElem.RES_SAIDI:
            case AbsElem.RES_SAIFI:
            case AbsElem.RES_VOLT_MAG_NODE1:
            case AbsElem.RES_VOLT_ANG_NODE1:
            case AbsElem.RES_VOLT_SAGS_ON_TGT:
            case AbsElem.RES_VOLT_SAGS_NODE1:
            case AbsElem.RES_PROTECT_ZONE:
            case AbsElem.RES_SA_MOMENT_INT:
            case AbsElem.RES_SA_SUST_INT:
            case AbsElem.RES_SA_DUR_SI:
            case AbsElem.RES_OLV_MI:
            case AbsElem.RES_OLV_SI:
            case AbsElem.RES_OLV_DUR_SI:
            case AbsElem.RES_UVV_MI:
            case AbsElem.RES_UVV_SI:
            case AbsElem.RES_UVV_DUR_SI:
                return true;
            default:
                return false;
        }
    }
}